package com.wus.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wus.common.core.exception.BusinessException;
import com.wus.system.entity.SysDictData;
import com.wus.system.entity.SysDictType;
import com.wus.system.mapper.SysDictDataMapper;
import com.wus.system.mapper.SysDictTypeMapper;
import com.wus.system.request.SysDictTypeAddReq;
import com.wus.system.request.SysDictTypeDeleteReq;
import com.wus.system.request.SysDictTypeQueryReq;
import com.wus.system.request.SysDictTypeUpdateReq;
import com.wus.system.response.SysDictTypeResp;
import com.wus.system.service.ISysDictTypeService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * <p>
 * 字典类型表 服务实现类
 * </p>
 *
 * @author wus
 * @since 2025-01-06
 */
@RequiredArgsConstructor
@Service
public class SysDictTypeServiceImpl implements ISysDictTypeService {

    private final Logger logger = LoggerFactory.getLogger(SysDictTypeServiceImpl.class);

    private final SysDictTypeMapper baseMapper;

    private final SysDictDataMapper dictDataMapper;

    @Override
    public Boolean add(SysDictTypeAddReq req) {
        if (checkUniqueDictTypeIsExisted(req.getDictType(), null)) {
            throw BusinessException.newInstance("字典类型已存在");
        }
        SysDictType sysDictType = new SysDictType();
        BeanUtils.copyProperties(req, sysDictType);
        return baseMapper.insert(sysDictType) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean delete(SysDictTypeDeleteReq req) {
        List<SysDictType> dictTypeList = baseMapper.selectBatchIds(req.getIds());
        if(!dictTypeList.isEmpty()) {
            // 同时删除字典类型下的键值对
            List<String> typeNameList = dictTypeList.stream().map(SysDictType::getDictType).toList();
            dictDataMapper.delete(Wrappers.<SysDictData>lambdaQuery().in(SysDictData::getDictType, typeNameList));
        }
        return baseMapper.deleteBatchIds(req.getIds()) > 0;
    }

    @Override
    public Boolean update(SysDictTypeUpdateReq req) {
        if (checkUniqueDictTypeIsExisted(req.getDictType(), req.getId())) {
            throw BusinessException.newInstance("字典类型已存在");
        }
        if (baseMapper.selectById(req.getId()) == null) {
            throw BusinessException.newInstance("记录不存在");
        }
        SysDictType sysDictType = new SysDictType();
        BeanUtils.copyProperties(req, sysDictType);
        return baseMapper.update(sysDictType, Wrappers.<SysDictType>lambdaUpdate().eq(SysDictType::getId, req.getId())) > 0;
    }

    @Override
    public List<SysDictTypeResp> list(SysDictTypeQueryReq req) {
        List<SysDictType> dictTypeList = baseMapper.selectList(Wrappers.<SysDictType>lambdaQuery()
                .like(StrUtil.isNotBlank(req.getKeyword()), SysDictType::getDictName, req.getKeyword())
                .or()
                .like(StrUtil.isNotBlank(req.getKeyword()), SysDictType::getDictType, req.getKeyword()));
        return dictTypeList.stream().map(dictType -> {
            SysDictTypeResp resp = new SysDictTypeResp();
            BeanUtils.copyProperties(dictType, resp);
            return resp;
        }).toList();
    }

    @Override
    public SysDictTypeResp getDetailById(Long id) {
        SysDictType dictType = baseMapper.selectById(id);
        if (dictType == null) {
            throw BusinessException.newInstance("记录不存在");
        }
        SysDictTypeResp resp = new SysDictTypeResp();
        BeanUtils.copyProperties(dictType, resp);
        return resp;
    }

    private boolean checkUniqueDictTypeIsExisted(String dictType, Long excludeId) {
        return baseMapper.selectCount(Wrappers.<SysDictType>lambdaQuery()
                .ne(excludeId != null, SysDictType::getId, excludeId)
                .eq(SysDictType::getDictType, dictType)
        ) > 0;
    }
}
